using UnityEngine;
using UnityEngine.EventSystems;

namespace Gj
{
    public class DragItemHelper : NodeHelper, IPointerDownHandler, IPointerUpHandler, IDragHandler
    {
        public float x;
        public float y;
        public bool allowDrag;
        public RectTransform rectTransform;
        public DragListHelper parent;
        private bool drag;
        private Vector2 dragPoint;
        private Vector3 endP;
        private float endTime;
        private Vector3 startP;

        [HideInInspector]
        public float width
        {
            get => rectTransform.rect.width;
            set => rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, value);
        }

        [HideInInspector]
        public float height
        {
            get => rectTransform.rect.height;
            set => rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, value);
        }

        private void Update()
        {
            if (endTime > 0)
            {
                endTime -= Time.deltaTime;
                if (endTime <= 0)
                {
                    endTime = 0;
                    transform.localPosition = endP;
                }
                else
                {
                    transform.localPosition = MathTools.Lerp(startP, endP,
                        MathTools.Compute(parent.easeType, 1, 0, endTime / parent.time));
                }
            }
        }

        public void OnDrag(PointerEventData eventData)
        {
            if (drag)
            {
                var p = transform.position;
                if (parent.vertical)
                {
                    if (parent.allowOut)
                    {
                        p.y = eventData.position.y;
                        p.x = eventData.position.x;
                    }
                    else if (parent.OutTop(eventData.position.y - parent.transform.position.y))
                    {
                        p.y = parent.top + parent.transform.position.y;
                    }
                    else if (parent.OutBottom(eventData.position.y - parent.transform.position.y))
                    {
                        p.y = parent.bottom + parent.transform.position.y;
                    }
                    else
                    {
                        p.y = eventData.position.y;
                    }
                }

                if (parent.horizontal)
                {
                    if (parent.allowOut)
                    {
                        p.y = eventData.position.y;
                        p.x = eventData.position.x;
                    }
                    else if (parent.OutRight(eventData.position.x - parent.transform.position.x))
                    {
                        p.x = parent.right + parent.transform.position.x;
                    }
                    else if (parent.OutLeft(eventData.position.x - parent.transform.position.x))
                    {
                        p.x = parent.left + parent.transform.position.x;
                    }
                    else
                    {
                        p.x = eventData.position.x;
                    }
                }

                transform.position = p;
                parent.Check((int)transform.localPosition.x, (int)transform.localPosition.y, index);
            }
        }

        public void OnPointerDown(PointerEventData eventData)
        {
            if (!parent.allowDrag) return;
            if (!allowDrag) return;
            dragPoint = eventData.position;
            transform.SetParent(null, false);
            transform.SetParent(parent.transform, false);
            drag = true;
            parent.StartDrag(index);
            Emit(UIEvent.Select);
        }

        public void OnPointerUp(PointerEventData eventData)
        {
            if (!parent.allowDrag) return;
            if (!allowDrag) return;
            drag = false;
            parent.EndDrag();
        }

        public void OnInit(DragListHelper list)
        {
            gameObject.SetActive(true);
            parent = list;
        }

        public void OnClear()
        {
            Emit(UIEvent.Del);
            // Destroy(gameObject);
        }

        public void OnChange(int i)
        {
            if (i != index) Change(i);
        }

        public void OnChange(float _x, float _y)
        {
            if (drag) return;
            x = _x;
            y = _y;
            endP = new Vector3(_x, _y, 0);
            if (endP != transform.localPosition)
            {
                endTime = parent.time;
                startP = transform.localPosition;
            }
        }
    }
}